package com.mutouren.common.orm.spring;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import com.mutouren.common.exception.ExceptionUtils;
import com.mutouren.common.utils.StringUtils;

public class DataSourceAspect {
	
	public void before(JoinPoint point) {
		
		DataSource source = null;
		
		Object target = point.getTarget();
		String method = point.getSignature().getName();

		Class<?>[] interfaces = target.getClass().getInterfaces();
		Class<?>[] parameterTypes = ((MethodSignature) point.getSignature()).getMethod().getParameterTypes();
		
		try {
			do {	
				// 优先级: 类方法、类、接口方法、接口				
				Method m = target.getClass().getMethod(method, parameterTypes);
				if (m != null && m.isAnnotationPresent(DataSource.class)) {
					source = m.getAnnotation(DataSource.class);
					break;
				}
				if (target.getClass().isAnnotationPresent(DataSource.class)) {
					source = target.getClass().getAnnotation(DataSource.class);
					break;
				}
				
				if (interfaces.length == 0) break;
				m = interfaces[0].getMethod(method, parameterTypes);
				if (m != null && m.isAnnotationPresent(DataSource.class)) {
					source = m.getAnnotation(DataSource.class);
					break;
				}
				if (interfaces[0].isAnnotationPresent(DataSource.class)) {
					source = interfaces[0].getAnnotation(DataSource.class);
					break;
				}				
				
			} while(false);
		} catch(Throwable t) {
			throw ExceptionUtils.doUnChecked(t);
		}
		
		if (source == null) return;
		checkDataSource(source);
		DataSourceSynchronizationManager.setDataSource(source);
	}
	
	private void checkDataSource(DataSource ds) {
		if (ds == null) return;
		
		if (StringUtils.isBlank(ds.name())) {
			throw new RuntimeException("DataSourceInfo error: name is blank");
		}		
		if (ds.isSlave() && (ds.slaveCount() < 1)) {
			throw new RuntimeException("DataSourceInfo error: when isSlave = true, slaveCount must > 0");
		}
	}
	
}